package cn.tedu.tmall.front.content.controller;

import cn.tedu.tmall.common.pojo.PageData;
import cn.tedu.tmall.front.content.pojo.vo.ArticleVo;
import cn.tedu.tmall.front.content.pojo.vo.CategoryVo;
import cn.tedu.tmall.front.content.service.IArticleService;
import cn.tedu.tmall.front.content.service.ICategoryService;
import cn.tedu.tmall.common.web.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Range;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * 资讯分类接口
 * 1 分类列表
 * 2 通过分类id查询文章列表
 * 3 通过文章id查询文章详情
 */
@Slf4j
@RestController
@RequestMapping("/categories")
@Api(tags = "商城资讯前台分类接口")
@Validated
public class CategoryController {


    @Autowired
    private ICategoryService categoryService;

    @Autowired
    private IArticleService articleService;

    /**
     * 分类列表
     * @return 分类列表
     */
    @ApiOperation("分类列表")
    @GetMapping("/category/list")
    public JsonResult listCategory(){
        log.debug("查询分类列表");
        List<CategoryVo> categoryVos = categoryService.listCategory();
        log.debug("查询分类列表 结果:{}",categoryVos);
        return JsonResult.ok(categoryVos);
    }


    /**
     * 通过分类id查询文章列表
     * @param categoryId 分类id
     * @param pageNum 当前第几页
     * @param pageSize 每页显示多少条
     * @return 文章列表
     * 完整地址
     * GET http://localhost:8080/categories/category/article/11
     */
    @ApiOperation("通过分类id查询文章列表")
    //ApiImplicitParams 在多个入参的情况下使用
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId",value="分类id",required = true,dataType = "Long"),
            @ApiImplicitParam(name = "pageNum",value="当前页码",required = true,dataType = "Long"),
            @ApiImplicitParam(name = "pageSize",value="每页行数",required = true,dataType = "Long")
    })
    @GetMapping("/category/article/list/{categoryId}/{pageNum}/{pageSize}")
    public JsonResult listArticleById(
            @PathVariable
            @Range(min = 1,message = "请输入有效的分类id") Long categoryId,
            @PathVariable
            @Range(min = 1,message = "请输入有效的页码") Integer pageNum,
            @PathVariable
            @Range(min = 1,max = 50,message = "请输入有效的pageSize") Integer pageSize
        ){
        //如果pageSize传入一个很大的值 500000 可能导致内存溢出 数据太多我们的内存放不下了,OutMemoryException
        //我们项目打印日志的目的是什么?
        // 1 定位问题
        // 2 快速排查
        //日志规范,每个公司都有不同的规范.
        // 1 都会有什么问题?
        //   接口地址未找到 404
        //   前端接口调用方传入的参数有问题, 举例 分类id 传入 -1,传了一个字符串.
        //   我们的代码逻辑有问题 .我们的锅

        log.debug("通过分类id查询文章列表接口-入参 " +
                "分类id:{},当前页数:{},每页行数:{}",categoryId,pageNum,pageSize);
        //JsonResult jsonResult = new JsonResult();
        //jsonResult.setState(200);
        //jsonResult.setData(getMockArticleList(categoryId));
        //return jsonResult;
        //我们的接口直接return 行不行 ?
        //
        log.debug("通过分类id查询文章列表-调用方法-入参 分类id:{}",categoryId);
        //List<ArticleVo> mockArticleList = getMockArticleList(categoryId);
        PageData<ArticleVo> articleVoList =  articleService.getArticleByCategoryId(categoryId,pageNum,pageSize);
        //返回了两条记录
        log.debug("通过分类id查询文章列表-调用方法-入参 分类id:{},出参:{}",categoryId,articleVoList);
        JsonResult ok = JsonResult.ok(articleVoList);
        log.debug("通过分类id查询文章列表接口-入参 分类id:{},当前页数:{},每页行数:{},出参:{}",
                categoryId,pageNum,pageSize,ok);
        //20000 表示ok
        //前端工程说 if(state == 20000) {
        //    渲染页面.
        // mockArticleList 处理逻辑有问题,本来我的服务器的逻辑是返回了两条记录
        // 搞丢一条,
        // }
        //如果前端的老哥,疏忽if(state != 20000){
        //   渲染页面
        // }
        //
        return ok;
    }

    /**
     * 模拟文章列表数据
     * @return
     */
    private List<ArticleVo> getMockArticleList(Long categoryId){
        List<ArticleVo> result = new ArrayList<>();

        ArticleVo articleVo = new ArticleVo();
        articleVo.setTitle("深山里的冻绿茶叶");
        articleVo.setAuthor("管理员");
        articleVo.setDigest("冻绿茶叶真好喝");
        articleVo.setPic("http://pic.tea/a.jpg");
        articleVo.setCategoryId(categoryId);


        ArticleVo articleVo1 = new ArticleVo();
        articleVo1.setTitle("深山里的冻绿茶叶");
        articleVo1.setAuthor("管理员");
        articleVo1.setDigest("冻绿茶叶真好喝");
        articleVo1.setPic("http://pic.tea/a.jpg");
        articleVo1.setCategoryId(categoryId);

        result.add(articleVo);
        result.add(articleVo1);
        //throw new RuntimeException();
        return result;
    }

    /**
     * 通过文章id查询文章详情
     * @param articleId 文章id
     * @return 文章详情
     * GET http://localhost:8080/categories/category/article/11
     * restful  资源进行描述
     *
     *  资源/动作
     *  资源 /category/article/
     *  动作 list
     *  /category/article/list/{categoryId}
     *  /category/article/detail/{articleId}
     *
     *  动作/资源
     *  /detail/category/article/{articleId}
     *  /list/category/article/{categoryId}
     *
     *  不推荐这么写
     *  一会资源在前,一会动作在前 不规范
     *  /detail/category/article/{articleId}
     *  /category/article/list/{articleId}
     *
     *  不推荐这么
     *  方法的命名更建议驼峰
     *  接口地址不建议驼峰
     *  /getArticleById
     *
     */
    //@GetMapping("/getArticleById")
    @ApiOperation("通过文章id查询文章详情")
    @ApiImplicitParam(name = "articleId",value="文章id",required = true,dataType = "Long")
    @GetMapping("/category/article/detail/{articleId}")
    public JsonResult getArticleById(
            @PathVariable
            @Range(min = 1,message = "请输入有效的文章id") Long articleId) {
        log.debug("通过文章id查询文章详情 入参:{}",articleId);
        ArticleVo articleVo = articleService.getArticleById(articleId);
        log.debug("通过文章id查询文章详情 入参:{},结果:{}",articleId,articleVo);
        return JsonResult.ok(articleVo);
    }





}
